#include <stdlib.h>
#include <pic18f6722.h>

#define uint unsigned int
#define uchar unsigned char
#define uchar unsigned char
#define uint unsigned int

#define GAS_GAUGE_ALCC  RC7     //LTC2943 ALCC PIN
#define ALCC_HIG_TO_LOW RB1
void Device_LTC2943_Initialize(void);
unsigned char Device_PowerCheckALCC(void);
void Device_LTC2943_WriteByte(unsigned char address,unsigned char dataByte);
unsigned char  Device_LTC2943_ReadByte(unsigned int address);
unsigned char Device_LTC2943_AlertResponse();
unsigned int Device_LTC2943_AccumulatedCharge();
unsigned int Device_LTC2943_ReadCurrent();
void Device_LTC2943_Init_AccCharge();

extern void PIC_IIC_Delayus();
extern void PIC_IIC_Delayms(unsigned int ms);
extern void PIC_Write_Char_To_EEPROM(uint Addr, uchar Data);
extern uchar PIC_Read_Char_From_EEPROM(uint Addr);
extern void PIC_IIC_Initialize();
extern void PIC_IIC_Start();
extern void PIC_IIC_Stop();
extern void PIC_IIC_SendByte(unsigned char byteData);
extern unsigned char PIC_IIC_ReadByte();
extern unsigned char PIC_IIC_CheckACK();
extern void PIC_IIC_SendACK(unsigned char b_ACK);
extern void Device_LTC2943_Init_AccCharge();



//*********************************************************************
/* Initialize LTC2943
 * input void 
 * return: void
 * author: Guichuan.He
 * date: 2016-9-23
*/
//**********************************************************************
void Device_LTC2943_Initialize(void)
{
    
  
   Device_LTC2943_WriteByte(0x01,0xcd);
   // Automatic Mode: continuously performing voltage current and temperature conversions
   // Set coulomb counter prescaling facotr M = 4096
   // Alert Mode: alert functionality enabled. pin becomes logic output
   // turn on analog section
   
 //  (0x08);
//   Device_LTC2943_ReadByte(0x09);
//Set valtage Threhold high
//   Device_LTC2943_WriteByte(0x0b,0xdc);
    //Set valtage Threhold low
   Device_LTC2943_WriteByte(0x0c,0x1f);
   Device_LTC2943_WriteByte(0x0d,0x75);
   Device_LTC2943_WriteByte(0x02,0x75);
   Device_LTC2943_WriteByte(0x03,0xa5); 
 //  Device_LTC2943_WriteByte(0x02,0x7f);  
 //  Device_LTC2943_WriteByte(0x03,0xff);  
 //  Device_LTC2943_WriteByte(0x04,0xff);  
 //  Device_LTC2943_WriteByte(0x05,0xff); 
  //    Device_LTC2943_WriteByte(0x01,0xcd);
 //  Device_LTC2943_WriteByte(0x01,0xcc);
   Device_LTC2943_WriteByte(0x01,0x0d);
   Device_LTC2943_WriteByte(0x01,0x0c);
   Device_LTC2943_Init_AccCharge();
   
 
 
}

//********************************************************************
/* Check LTC2943 ALCC PIN. It behaves as an open-drain logic
 * output that pulls to GND when any threshold register value
 * is exceeded.
 * input: void
 * return: 0 - LTC2943 any threshold register value is exceeded.
 *         1 - threshold register value is in normal range.
 * author: Guichuan.He
 * date: 2016-9-26
*/
//**********************************************************************
uchar Device_LTC2943_CheckALCC()
{
   if( GAS_GAUGE_ALCC == 1 )
       return 1;
   else
       return 0;
}

//********************************************************************
/* When read the LTC alert response address(ARA), the LTC2943 will stop pulling down the ALCC pin.
 * input: void
 * return: 
 * author: Guichuan.He
 * date: 2016-10-24
*/
//**********************************************************************
unsigned char Device_LTC2943_AlertResponse()
{
    unsigned char AlertResponseValue;
    
   PIC_IIC_Start();
   PIC_IIC_SendByte(0x19);
   PIC_IIC_CheckACK();
   AlertResponseValue = PIC_IIC_ReadByte();
   PIC_IIC_SendACK(1);
   PIC_IIC_Stop();
   
   return AlertResponseValue;
}

//********************************************************************
/* read voltage from LTC2943
 * input: void
 * return: battery voltage  unit 0.01
 * author: Guichuan.He
 * date: 2016-10-21
*/
//**********************************************************************
unsigned int Device_LTC2943_ReadVoltage()
{
    unsigned int ch_MSB,ch_LSB;
    unsigned long int Battery_Voltage;
	PIC_IIC_Start();  
    
    PIC_IIC_SendByte(0xC8);        
    PIC_IIC_CheckACK();               
           
    PIC_IIC_SendByte(0x08);    
    PIC_IIC_CheckACK();   
    
    PIC_IIC_Start();                 
    PIC_IIC_SendByte(0xC9);         
    PIC_IIC_CheckACK();      
    
    ch_MSB = PIC_IIC_ReadByte();  
    PIC_IIC_SendACK(0);  
    ch_LSB = PIC_IIC_ReadByte();  
    PIC_IIC_SendACK(1);  
   
    PIC_IIC_Stop(); 
     
    Battery_Voltage = (( ch_MSB << 0x08 ) + ch_LSB);
    Battery_Voltage = Battery_Voltage *0.009155;
   
    
    return  Battery_Voltage;
}

//********************************************************************
/* read Current from LTC2943
 * input: void
 * return: battery Current  unit 0.001mAh
 * author: Guichuan.He
 * date: 2016-10-21
*/
//**********************************************************************
 unsigned int Device_LTC2943_ReadCurrent()
{
    unsigned int ch_MSB,ch_LSB;
    long int Battery_Current;
    int Charge_Current;
    
	PIC_IIC_Start();  
    
    PIC_IIC_SendByte(0xC8);        
    PIC_IIC_CheckACK();               
           
    PIC_IIC_SendByte(0x02);    
    PIC_IIC_CheckACK();   
    
    PIC_IIC_Start();                 
    PIC_IIC_SendByte(0xC9);         
    PIC_IIC_CheckACK();      
    
    ch_MSB = PIC_IIC_ReadByte();  
    PIC_IIC_SendACK(0);  
    ch_LSB = PIC_IIC_ReadByte();  
    PIC_IIC_SendACK(1);  
   
    PIC_IIC_Stop(); 
     
    Battery_Current = (( ch_MSB << 0x08 ) + ch_LSB);
    
  // Charge_Current = 0.085*Battery_Current/128;
  // Charge_Current = 0.085*Battery_Current/128*1000;
  //  Charge_Current = 0.6640625*Battery_Current;
  //  return  Charge_Current;
    
    return Battery_Current;
}

//********************************************************************
/* read Accumulated Charge from LTC2943
 * input: void
 * return: the amount of charge
 * author: Guichuan.He
 * date: 2016-10-24
*/
//**********************************************************************
unsigned int Device_LTC2943_AccumulatedCharge()
{
    unsigned int ch_MSB,ch_LSB;
    unsigned long int AccumulatedCharge;
	PIC_IIC_Start();  
    
    PIC_IIC_SendByte(0xC8);        
    PIC_IIC_CheckACK();               
           
    PIC_IIC_SendByte(0x02);    
    PIC_IIC_CheckACK();   
    
    PIC_IIC_Start();                 
    PIC_IIC_SendByte(0xC9);         
    PIC_IIC_CheckACK();      
    
    ch_MSB = PIC_IIC_ReadByte();  
    PIC_IIC_SendACK(0);  
    ch_LSB = PIC_IIC_ReadByte();  
    PIC_IIC_SendACK(1);  
   
    PIC_IIC_Stop(); 
     
    AccumulatedCharge = (( ch_MSB << 0x08 ) + ch_LSB);
 //   AccumulatedCharge = AccumulatedCharge   *100;
 //   AccumulatedCharge = AccumulatedCharge/2777;
    
    return  AccumulatedCharge;
}

//********************************************************************
/* read a byte from LTC2943
 * input: unsigned int address,
 * return: unsigned char
 * author: Guichuan.He
 * date: 2016-9-26
*/
//**********************************************************************
unsigned char  Device_LTC2943_ReadByte(unsigned int address) 
{
    unsigned char ch;

    PIC_IIC_Start();
    PIC_IIC_SendByte(0xC8);
    PIC_IIC_CheckACK();

    PIC_IIC_SendByte(address & 0xff);
    PIC_IIC_CheckACK();

    PIC_IIC_Start();

    PIC_IIC_SendByte(0xC9);
    PIC_IIC_CheckACK();

    ch = PIC_IIC_ReadByte();
    PIC_IIC_SendACK(1);

    PIC_IIC_Stop();
    return ch;
}

//********************************************************************
/* Write a byte to LTC2943
 * input: unsigned int address,
 *        unsigned char dataByte
 * return: void
 * author: Guichuan.He
 * date: 2016-9-26
*/
//**********************************************************************
void Device_LTC2943_WriteByte(unsigned char address,unsigned char dataByte)
{
    PIC_IIC_Start();
    PIC_IIC_SendByte(0xC8);
    PIC_IIC_CheckACK();

    PIC_IIC_SendByte(address);
    PIC_IIC_CheckACK();

    PIC_IIC_SendByte(dataByte);
    PIC_IIC_CheckACK();

    PIC_IIC_Stop();
    PIC_IIC_Delayms(20);    
}
//********************************************************************
/* set accumulate charge to LTC2943
 * input: unsigned int accumulate,
 * return: void
 * author: Guichuan.He
 * date: 2016-9-26
*/
//**********************************************************************
void Device_LTC2943_Init_AccCharge()
{
   Device_LTC2943_WriteByte(0x01,0xcD);    //b0 = 1 shut down before cd
   
   Device_LTC2943_WriteByte(0x02,0x7f);
   Device_LTC2943_WriteByte(0x03,0xff);
   
   Device_LTC2943_WriteByte(0x01,0xcC);   //b0 =0  //cc
}
unsigned char Device_PowerCheckALCC(void)
{
    return ALCC_HIG_TO_LOW;
}
